import java.io.File;
import java.io.IOException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;

/**
 * This class handles playback of audio files
 */
public class AudioPlayer extends Thread{

	private static final int EXTERNAL_BUFFER_SIZE = 128000;
	private File soundFile;			//the audio file to play
	private volatile boolean done;	//true iff thread should stop

	/**
	 * @param filename
	 */
	public AudioPlayer(File soundFile) {
		this.soundFile = soundFile;
	}

	/**
	 * Plays the audio file
	 */
	public void run(){
			AudioInputStream	audioInputStream = null;
			try
			{
				audioInputStream = AudioSystem.getAudioInputStream(soundFile);
			}
			catch (Exception e)
			{
				return;
			}
			AudioFormat	audioFormat = audioInputStream.getFormat();
			SourceDataLine	line = null;
			DataLine.Info	info = new DataLine.Info(SourceDataLine.class,
					audioFormat);
			try
			{
				line = (SourceDataLine) AudioSystem.getLine(info);
				line.open(audioFormat);
			}
			catch (LineUnavailableException e)
			{
				e.printStackTrace();
				System.exit(1);
			}
			catch (Exception e)
			{
				e.printStackTrace();
				System.exit(1);
			}

			line.start();
			int	nBytesRead = 0;
			byte[]	abData = new byte[EXTERNAL_BUFFER_SIZE];
			while (nBytesRead != -1 && !done)
			{
				try
				{
					nBytesRead = audioInputStream.read(abData, 0, abData.length);
				}
				catch (IOException e)
				{
					e.printStackTrace();
				}
				if (nBytesRead >= 0)
				{
					@SuppressWarnings("unused")
					int	nBytesWritten = line.write(abData, 0, nBytesRead);
				}
			}
			line.drain();
			line.close();
	}

	/**
	 * signals that the thread should stop playing
	 */
	public void done(){
		done = true;
	}

}
